package ai

import (
	"encoding/json"
	"fmt"
	"os"

	"anders-cli/internal/config"

	"github.com/go-resty/resty/v2"
)

// LMStudioBackend LMStudio AI后端实现
type LMStudioBackend struct {
	client  *resty.Client
	baseURL string
	model   string
}

// NewLMStudioBackend 创建新的LMStudio后端实例
func NewLMStudioBackend() *LMStudioBackend {
	cfg := config.Get()

	return &LMStudioBackend{
		client:  resty.New(),
		baseURL: cfg.LMStudio.BaseURL,
		model:   cfg.LMStudio.Model,
	}
}

// Name 返回后端名称
func (b *LMStudioBackend) Name() string {
	return "LMStudio"
}

// GetModel 返回当前使用的模型名称
func (b *LMStudioBackend) GetModel() string {
	return b.model
}

// Query 执行AI查询
func (b *LMStudioBackend) Query(prompt string, tools []Tool) (string, error) {
	return b.QueryWithReasoning(prompt, tools, nil)
}

// QueryWithReasoning 执行AI查询并返回推理过程
func (b *LMStudioBackend) QueryWithReasoning(prompt string, tools []Tool, reasoningCallback func(string)) (string, error) {
	// 构建请求消息
	messages := []Message{
		{
			Role:    "user",
			Content: prompt,
		},
	}

	// 构建请求体
	requestBody := map[string]interface{}{
		"model":       b.model,
		"messages":    messages,
		"temperature": 0.7,
		"max_tokens":  1000,
	}

	// 如果有工具，添加到请求中
	if len(tools) > 0 {
		requestBody["tools"] = tools
		requestBody["tool_choice"] = "auto"
	}

	// 发送请求
	resp, err := b.client.R().
		SetHeader("Content-Type", "application/json").
		SetBody(requestBody).
		Post(b.baseURL + "/v1/chat/completions")

	if err != nil {
		return "", fmt.Errorf("LMStudio 请求失败: %v", err)
	}

	if resp.StatusCode() != 200 {
		return "", fmt.Errorf("LMStudio API 返回错误状态码: %d", resp.StatusCode())
	}

	// 解析响应
	var response struct {
		Choices []struct {
			Message struct {
				Content   string `json:"content"`
				Reasoning string `json:"reasoning"` // LMStudio推理过程
				ToolCalls []struct {
					Function struct {
						Name      string          `json:"name"`
						Arguments json.RawMessage `json:"arguments"`
					} `json:"function"`
				} `json:"tool_calls,omitempty"`
			} `json:"message"`
		} `json:"choices"`
	}

	if err := json.Unmarshal(resp.Body(), &response); err != nil {
		return "", fmt.Errorf("解析响应失败: %v", err)
	}

	if len(response.Choices) == 0 {
		return "", fmt.Errorf("未收到有效响应")
	}

	message := response.Choices[0].Message
	content := message.Content

	// 如果有推理过程且提供了回调函数，则调用回调显示思考过程
	if message.Reasoning != "" && reasoningCallback != nil {
		reasoningCallback(message.Reasoning)
	}

	return content, nil
}

// getAPIKey 获取API密钥
func (b *LMStudioBackend) getAPIKey() string {
	cfg := config.Get()
	if cfg.LMStudio.ApiKeyEnv != "" {
		return os.Getenv(cfg.LMStudio.ApiKeyEnv)
	}
	// LMStudio 通常不需要 API key
	return "not-needed"
}
